import { useModel } from "@umijs/max"
import type { TableProps } from "antd"
import {
  App,
  Form,
  Input,
  InputNumber,
  Popconfirm,
  Select,
  Table,
  Typography
} from "antd"
import React, { useEffect, useState } from "react"

interface DataType {
  key: number
  username: string
  password: string
  role: string
  registerTime: string
  lastLoginTime: string
}

interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
  editing: boolean
  dataIndex: string
  title: any
  inputType: "number" | "text" | "select"
  record: DataType
  index: number
}

const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
  editing,
  dataIndex,
  title,
  inputType,
  record,
  index,
  children,
  ...restProps
}) => {
  let inputNode
  if (inputType === "number") {
    inputNode = <InputNumber />
  } else if (inputType === "text") {
    inputNode = <Input />
  } else {
    // select相关
    if (dataIndex === "role") {
      inputNode = (
        <Select>
          <Select.Option value="普通用户">普通用户</Select.Option>
          <Select.Option value="维护人员">维护人员</Select.Option>
        </Select>
      )
    } else if (dataIndex === "operation_mode") {
      inputNode = (
        <Select>
          <Select.Option value="自动模式">自动模式</Select.Option>
          <Select.Option value="手动模式">手动模式</Select.Option>
          <Select.Option value="半自动模式">半自动模式</Select.Option>
        </Select>
      )
    }
  }

  return (
    <td {...restProps}>
      {editing ? (
        <Form.Item
          name={dataIndex}
          style={{ margin: 0 }}
          rules={[
            {
              required: dataIndex !== "registerTime" && dataIndex !== "lastLoginTime",
              message: `Please Input ${title}!`
            }
          ]}
        >
          {inputNode}
        </Form.Item>
      ) : (
        children
      )}
    </td>
  )
}

const EapParamsForm: React.FC = () => {
  const [form] = Form.useForm()
  const [data, setData] = useState<DataType[]>([])
  const [editingKey, setEditingKey] = useState(0)
  // 是否重新加载数据
  const [isReload, setIsReload] = useState(true)

  const { wsIsOpenRef, callPy } = useModel("websocketModel")
  const { message } = App.useApp()

  useEffect(() => {
    console.log("EapParamsForm 表单初始化")
    const fetchData = async () => {
      try {
        const response = await callPy("ec", "get_eap_params_from_web", [])
        if (response.state) {
          setData(response.data)
        } else {
          message.error("表单数据获取失败:" + response.info)
          setData([])
        }
      } catch (error) {
        console.log("数据加载失败", error)
      } finally {
        // 这一步很重要,不然下一次isReload为True的时候收不到变化
        setIsReload(false)
      }
    }

    if (isReload) {
      if (wsIsOpenRef.current) {
        fetchData()
      } else {
        setTimeout(() => {
          fetchData()
        }, 200)
      }
    }
  }, [isReload])
  const isEditing = (record: DataType) => record.key === editingKey

  const edit = (record: Partial<DataType> & { key: React.Key }) => {
    form.setFieldsValue({ ...record })
    setEditingKey(record.key)
  }

  const cancel = () => {
    setEditingKey(0)
  }

  const save = async (key: number) => {
    try {
      const row = (await form.validateFields()) as DataType
      const newData = { ...row, key: key }
      const response = await callPy("ec", "save_eap_params_from_web", [newData])
      setEditingKey(0)
      if (response.state) {
        message.success("保存成功")
      } else {
        message.error("保存失败: " + response.info, 3)
      }
      setIsReload(true)
    } catch (errInfo) {
      console.log("Validate Failed:", errInfo)
    }
  }

  const columns = [
    {
      title: "设备ID",
      dataIndex: "user_id",
      inputType: "text",
      editable: true
    },
    {
      title: "EapIP",
      dataIndex: "server_ip",
      inputType: "text",
      editable: true
    },
    {
      title: "本机端口",
      dataIndex: "pc_port",
      inputType: "number",
      editable: true
    },
    {
      title: "操作模式",
      dataIndex: "operation_mode",
      inputType: "select",
      editable: true
    },
    {
      title: "心跳周期",
      dataIndex: "ask_duration",
      inputType: "number",
      editable: true
    },
    {
      title: "时间周期",
      dataIndex: "time_report_duration",
      inputType: "number",
      editable: true
    },
    {
      title: "数量周期",
      dataIndex: "wip_count_duration",
      inputType: "number",
      editable: true
    },
    {
      title: "移动速度",
      dataIndex: "move_speed",
      inputType: "number",
      editable: true
    },
    {
      title: "回退速度",
      dataIndex: "back_speed",
      inputType: "number",
      editable: true
    },
    {
      title: "机器人工作速度",
      dataIndex: "robot_work_speed",
      inputType: "number",
      editable: true
    },
    {
      title: "请求基础URL",
      dataIndex: "request_url_base",
      inputType: "text",
      editable: true
    },
    {
      title: "操作",
      with: "8%",
      render: (_: any, record: DataType) => {
        const editable = isEditing(record)
        return editable ? (
          <span>
            <Typography.Link
              onClick={() => save(record.key)}
              style={{ marginInlineEnd: 8 }}
            >
              保存
            </Typography.Link>
            <Popconfirm title="确定取消吗?" onConfirm={cancel}>
              <a>取消</a>
            </Popconfirm>
          </span>
        ) : (
          <span>
            <Typography.Link disabled={editingKey !== 0} onClick={() => edit(record)}>
              编辑
            </Typography.Link>
          </span>
        )
      }
    }
  ]

  const mergedColumns: TableProps<DataType>["columns"] = columns.map((col) => {
    if (!col.editable) {
      return col
    }
    return {
      ...col,
      onCell: (record: DataType) => ({
        record,
        inputType: col.inputType,
        dataIndex: col.dataIndex,
        title: col.title,
        editing: isEditing(record)
      })
    }
  })

  return (
    <Form form={form} component={false}>
      <Table<DataType>
        components={{
          body: { cell: EditableCell }
        }}
        bordered
        dataSource={data}
        columns={mergedColumns}
        rowClassName="editable-row"
        pagination={false}
      />
    </Form>
  )
}

export default () => (
  <App>
    <EapParamsForm />
  </App>
)
